package br.edu.fasete.javaroad.model;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;


public class EntityDescriptor {
	private String name;
	private EntityDescriptor superClass;
	private List<EntityDescriptor> subClasses;
	private List<AttributeDescriptor> attributeList = new ArrayList<AttributeDescriptor>(10);
	
	private List<ClassAssociationDescriptor> associationsManyToOne = new ArrayList<ClassAssociationDescriptor>(5);
	private List<ClassAssociationDescriptor> associationsOneToMany = new ArrayList<ClassAssociationDescriptor>(5);
	private List<ClassAssociationDescriptor> associationsOneToOne = new ArrayList<ClassAssociationDescriptor>(5);
	private List<ClassAssociationDescriptor> associationsManyToMany = new ArrayList<ClassAssociationDescriptor>(5);
	
	private List<MethodDescriptor> methods = new ArrayList<MethodDescriptor>(10);
	
	private List<FinderMethodDescriptor> daoMethods = new ArrayList<FinderMethodDescriptor>(5);
	private boolean subclass;
	private boolean dao;
	
	public boolean isDao() {
		return dao;
	}

	public void setDao(boolean dao) {
		this.dao = dao;
	}

	
	public void clear() {
		superClass = null;
		subClasses = new ArrayList<EntityDescriptor>(5);
		attributeList = new ArrayList<AttributeDescriptor>(10);
		associationsManyToOne = new ArrayList<ClassAssociationDescriptor>(5);
		associationsOneToMany = new ArrayList<ClassAssociationDescriptor>(5);
		associationsOneToOne = new ArrayList<ClassAssociationDescriptor>(5);
		associationsManyToMany = new ArrayList<ClassAssociationDescriptor>(5);
		methods = new ArrayList<MethodDescriptor>(10);
		daoMethods = new ArrayList<FinderMethodDescriptor>(5);
		subclass = false;
	}
	
	public EntityDescriptor() {
		clear();
	}
	
	public EntityDescriptor(String nome, boolean dao) {
		this();
		this.name = nome;
		this.dao = dao;
	}
	
	public List<FinderMethodDescriptor> getDaoMethods() {
		return daoMethods;
	}

	public void setDaoMethods(List<FinderMethodDescriptor> daoMethods) {
		this.daoMethods = daoMethods;
	}
	
	public List<AttributeDescriptor> getAttributeList() {
		return attributeList;
	}
	
	public List<AttributeDescriptor> getFullAttributeList() {
		List<AttributeDescriptor> attr = new ArrayList<AttributeDescriptor>();
		attr.addAll(attributeList);
		if(superClass != null) {
			attr.addAll(superClass.getFullAttributeList());
		}
		return attr;
	}
	
	public void setAttributeList(List<AttributeDescriptor> attributeList) {
		this.attributeList = attributeList;
	}
	
	public List<ClassAssociationDescriptor> getAssociationsManyToOne() {
		return associationsManyToOne;
	}
	
	public void setAssociationsManyToOne(
			List<ClassAssociationDescriptor> associationsManyToOne) {
		this.associationsManyToOne = associationsManyToOne;
	}
	
	public List<ClassAssociationDescriptor> getAssociationsOneToMany() {
		return associationsOneToMany;
	}
	
	public void setAssociationsOneToMany(
			List<ClassAssociationDescriptor> associationsOneToMany) {
		this.associationsOneToMany = associationsOneToMany;
	}
	
	
	public List<EntityDescriptor> getSubClasses() {
		return subClasses;
	}

	public void setSubClasses(List<EntityDescriptor> subClasses) {
		this.subClasses = subClasses;
	}

	public EntityDescriptor getSuperClass() {
		return superClass;
	}

	public List<ClassAssociationDescriptor> getAssociationsManyToMany() {
		return associationsManyToMany;
	}

	public void setAssociationsManyToMany(
			List<ClassAssociationDescriptor> associationsManyToMany) {
		this.associationsManyToMany = associationsManyToMany;
	}

	public void setSuperClass(EntityDescriptor superClass) {
		this.superClass = superClass;
		superClass.getSubClasses().add(this);
		this.setSubclass(true);
	}

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

	@Override
	public boolean equals(Object obj) {
		if(obj instanceof EntityDescriptor) {
			EntityDescriptor classe = (EntityDescriptor) obj;
			return this.getName().equals(classe.getName());
		}
		return false;
	}

	public boolean isSubclass() {
		return subclass;
	}

	public void setSubclass(boolean subclass) {
		this.subclass = subclass;
	}
	
	public String toString() {
		return this.name;
	}
	
	public Iterator<EntityDescriptor> getSuperclassIterator() {
		return new SuperClassIterator(this);
	}

	public List<MethodDescriptor> getMethods() {
		return methods;
	}

	public void setMethods(List<MethodDescriptor> methods) {
		this.methods = methods;
	}

	public List<ClassAssociationDescriptor> getAssociationsOneToOne() {
		return associationsOneToOne;
	}

	public void setAssociationsOneToOne(
			List<ClassAssociationDescriptor> associationsOneToOne) {
		this.associationsOneToOne = associationsOneToOne;
	}
	
	
	
}
